import type { Settings as LayoutSettings } from '@ant-design/pro-components';
import { SettingDrawer } from '@ant-design/pro-components';
import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
import { Spin } from "antd";
import { history } from '@umijs/max';
import {
  AvatarDropdown,
  AvatarName,
  Footer,
  Question,
} from '@/components';
import { currentUser, getLoginMenuTree } from '@/services/api';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';
import '@ant-design/v5-patch-for-react-19';
import { API_BASE_URL } from '../config/proxy';
import routes from '../config/routes';
import React from 'react';

const isDev = process.env.NODE_ENV === 'development';
const isDevOrTest = isDev || process.env.CI;
const loginPath = '/user/login';

/**
 * @see https://umijs.org/docs/api/runtime-config#getinitialstate
 * */
// 定义菜单树的类型
interface MenuItem {
  path?: string;
  name?: string;
  icon?: string;
  children?: MenuItem[];
  access?: string;
  [key: string]: any;
}

// 定义路由配置的类型
interface RouteConfig {
  path: string;
  name?: string;
  icon?: string;
  routes?: RouteConfig[];
  access?: string;
  layout?: boolean;
  component?: string;
  redirect?: string;
  [key: string]: any;
}

export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  currentUser?: API.CurrentUser;
  loading?: boolean;
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
  menuTree?: MenuItem[];
}> {
  const fetchUserInfo = async () => {
    try {
      const msg: any = await currentUser({
        skipErrorHandler: true,
      });
      return msg.result;
    } catch (_error) {
      history.push(loginPath);
    }
    return undefined;
  };

  // 从localStorage读取菜单树数据
  let menuTree: MenuItem[] = [];
  try {
    const storedMenuTree = localStorage.getItem('menuTree');
    if (storedMenuTree) {
      menuTree = JSON.parse(storedMenuTree);
    }
  } catch (error) {
    console.error('读取菜单树数据失败:', error);
  }

  // 如果不是登录页面，执行
  const { location } = history;
  if (
    ![loginPath, '/user/register', '/user/register-result'].includes(
      location.pathname,
    )
  ) {
    const currentUser = await fetchUserInfo();
    if (currentUser) {
      return {
        fetchUserInfo,
        currentUser,
        settings: defaultSettings as Partial<LayoutSettings>,
        menuTree: menuTree.length > 0 ? menuTree : undefined,
      };
    }
  }
  return {
    fetchUserInfo,
    settings: defaultSettings as Partial<LayoutSettings>,
    menuTree: menuTree.length > 0 ? menuTree : undefined,
  };
}

// 将路由配置转换为菜单配置的辅助函数
const routeToMenu = (route: RouteConfig): MenuItem => {
  const menuItem: MenuItem = {
    path: route.path,
    name: route.name,
    icon: route.icon,
    access: route.access,
  };

  // 处理子路由
  if (route.routes && route.routes.length > 0) {
    const validChildren = route.routes
      .filter(subRoute => !subRoute.redirect && subRoute.name)
      .map(subRoute => routeToMenu(subRoute));

    if (validChildren.length > 0) {
      menuItem.children = validChildren;
    }
  }

  return menuItem;
};

// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({
  initialState,
  setInitialState,
}) => {
  return {
    actionsRender: () => [
      <Question key="doc" />,
    ],
    avatarProps: {
      src: initialState?.currentUser?.avatar ? `${API_BASE_URL.replace(/:\d+\/?$/, '')}/${initialState.currentUser.avatar}` : './logo.png',
      title: <AvatarName />,
      render: (_, avatarChildren) => (
        <AvatarDropdown>{avatarChildren}</AvatarDropdown>
      ),
    },
    // waterMarkProps: {
    //   content: initialState?.currentUser?.realName,
    // },
    footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录，重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath);
      }
    },
    bgLayoutImgList: [
      {
        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
        left: 85,
        bottom: 100,
        height: '303px',
      },
      {
        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
        bottom: -68,
        right: -45,
        height: '303px',
      },
      {
        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
        bottom: 0,
        left: 0,
        width: '331px',
      },
    ],
    // links: isDevOrTest
    //   ? [
    //     <Link key="openapi" to="/umi/plugin/openapi" target="_blank">
    //       <LinkOutlined />
    //       <span>OpenAPI 文档</span>
    //     </Link>,
    //   ]
    //   : [],
    menuHeaderRender: undefined,
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    // 增加一个 loading 的状态
    childrenRender: (children) => {
      // if (initialState?.loading) return <PageLoading />;
      return (
        <>
          {children}
          {isDevOrTest && (
            <SettingDrawer
              disableUrlParams
              enableDarkTheme
              settings={initialState?.settings}
              onSettingChange={(settings) => {
                setInitialState((preInitialState) => ({
                  ...preInitialState,
                  settings,
                }));
              }}
            />
          )}
        </>
      );
    },
    // 整合API菜单树和静态路由配置
    menuDataRender: () => {
      // 从routes.ts获取静态菜单配置
      const staticMenu = (routes as RouteConfig[])
        .filter(route => route.layout !== false && route.name && route.path && route.path !== '/')
        .map(route => routeToMenu(route));

      // 如果有从API获取的菜单树，则将其与静态菜单合并
      if (initialState?.menuTree && initialState.menuTree.length > 0) {
        // 创建一个Set来存储已存在的路径，避免重复
        const existingPaths = new Set(staticMenu.map(item => item.path).filter(Boolean) as string[]);

        // 过滤API菜单树中不存在于静态菜单的项，且确保path存在
        const apiMenuItems = initialState.menuTree.filter(item => item.path && !existingPaths.has(item.path));

        // 合并静态菜单和API菜单
        return [...staticMenu, ...apiMenuItems];
      }

      // 否则只返回静态菜单
      return staticMenu;
    },
    // 禁用自动生成菜单，使用我们提供的菜单树
    disableContentMargin: false,
    // 配置路由映射菜单的方式
    route: {
      ignoreAccess: false,
      autoRoutes: true,
    },
    ...initialState?.settings,
  };
};

const contentStyle: React.CSSProperties = {
  padding: 50,
  background: 'rgba(0, 0, 0, 0.05)',
  borderRadius: 4,
};

const content = <div style={contentStyle} />;

// 创建一个高阶组件来处理动态加载
function lazyLoad(path: string) {
  const Component = React.lazy(() => import(`@/pages${path}`));
  return (
    <React.Suspense fallback={
      <Spin tip="Loading" size="large" >{content}</Spin>
    }>
      <Component />
    </React.Suspense>
  );
}

/**
 * @name patchClientRoutes 运行时客户端路由修改
 * @description 用于动态修改客户端路由配置，比patchRoutes更简单且不需要同时修改routeComponents
 * @doc https://umijs.org/docs/api/runtime-config#patchclientroutes
 */
export function patchClientRoutes({ routes }: { routes: any[] }) {
  const dynamicRoutes = window.__dynamicRoutes || [];

  // 找到主布局路由（通常是id为'ant-design-pro-layout'或path为'/'的路由）
  const layoutRoute = routes.find(r =>
    r.id === 'ant-design-pro-layout' ||
    r.path === '/'
  );

  if (layoutRoute) {
    // 确保子路由数组存在
    if (!layoutRoute.children) layoutRoute.children = [];
    if (!layoutRoute.routes) layoutRoute.routes = [];

    // 存储所有子路由，用于父路由的routes配置
    const allChildRoutes = [];

    // 处理动态路由数据
    dynamicRoutes.forEach((parentItem: any) => {
      // 检查父路由是否已存在
      const parentRouteExists = layoutRoute.routes.some((r: { path: string; }) => r.path === parentItem.path);

      if (!parentRouteExists && parentItem.children && parentItem.children.length > 0) {
        // 处理子路由
        const childRoutes: { path: any; }[] = [];

        parentItem.children.forEach((childItem: any) => {
          const childRoute = {
            path: childItem.path,
            name: childItem.name,
            access: childItem.permission || null,
            element: lazyLoad(childItem.component)
          };

          // 添加到子路由数组
          layoutRoute.children.push(childRoute);
          layoutRoute.routes.push(childRoute);
          childRoutes.push(childRoute);
          allChildRoutes.push(childRoute);
        });

        // 创建父路由
        const parentRoute = {
          path: parentItem.path,
          name: parentItem.name,
          access: parentItem.permission || null,
          routes: childRoutes,
          redirect: childRoutes.length > 0 ? childRoutes[0].path : undefined
        };

        // 添加父路由
        layoutRoute.children.unshift(parentRoute);
        layoutRoute.routes.unshift(parentRoute);
      } else {
        // 处理子路由
        const childRoutes: { path: any; }[] = [];
        const childRoute = {
          path: parentItem.path,
          name: parentItem.name,
          access: parentItem.permission || null,
          element: lazyLoad(parentItem.component)
        };
        // 添加到子路由数组
        layoutRoute.children.push(childRoute);
        layoutRoute.routes.push(childRoute);
        childRoutes.push(childRoute);
        allChildRoutes.push(childRoute);
      }
    });
  }
}

export async function render(oldRender: () => void) {
  try {
    const msg: any = await getLoginMenuTree({
      skipErrorHandler: true,
    });
    msg?.result?.forEach((item: { name: any; meta: { title: any; }; children: any[]; }): any => {
      item.name = item.meta.title;
      if (item.children && item.children.length > 0) {
        item.children.forEach((child): any => {
          child.name = child.meta.title;
        })
      }
    })
    localStorage.setItem('menuTree', JSON.stringify(msg.result));
    window.__dynamicRoutes = msg.result || [];
    // 简化render函数，直接执行原始的渲染函数
    oldRender();
  } catch (_error) {
    console.error('获取菜单树失败:', _error);
    oldRender();
  }
}

/**
 * @name request 配置，可以配置错误处理
 * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
 * @doc https://umijs.org/docs/max/request#配置
 */
export const request: RequestConfig = {
  baseURL: isDev ? '' : API_BASE_URL,
  ...errorConfig,
  requestInterceptors: [
    (config: any) => {
      const token = localStorage.getItem('accessToken');
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    },
  ],
};
